use core::fmt;

// 关联类型
pub trait Interator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}

struct Counter {
    current: u32,
    end: u32
}

// 关联函数new
impl Counter {
    fn new(current: u32, end: u32) -> Counter {
        Counter {
            current,
            end,
        }
    }
}

impl fmt::Display for Counter {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "current: {}, end: {}", self.current, self.end)
    }
}

impl Interator for Counter {
    type Item = u32;
    // 注意, 此处是Self::Item
    // 注意, 这里是&mut self
    fn next(&mut self) -> Option<Self::Item> {
        if self.current <= self.end {
            let current = self.current;
            self.current = self.current + 1;
            return Some(current);
        }
        return None;
    }
}
use std::{backtrace, ops};
fn main() {
    // 1. 关联类型
    let mut counter = Counter::new(1, 3);
    let step1 = counter.next();
    // {:?} 是一个用于调试的格式化占位符，它用于打印枚举（enum）、结构体（struct）等复合类型的详细表示
    println!("step1: {:?}", step1);
    let step2 = counter.next();
    println!("step2: {:?}", step2);
    let step3 = counter.next();
    println!("step3: {:?}", step3);
    let step4 = counter.next();
    println!("step4: {:?}", step4);
    // 2. 默认泛型参数和运算符重载
    #[derive(PartialEq, Debug)]
    struct Pointer {
        x: i32,
        y: i32
    }
    impl Pointer {
        fn new (x: i32, y: i32) -> Pointer {
            Pointer {
                x,
                y
            }
        }
    }
    impl ops::Add for Pointer {
        type Output = Pointer;
        fn add(self, rhs: Pointer) -> Self::Output {
            Pointer {
                x: self.x + rhs.x,
                y: self.y + rhs.y
            }
        }
    }
    let pointer1 = Pointer::new(1,2);
    let pointer2 = Pointer::new(9, 9);
    assert_eq!(pointer1 + pointer2, Pointer::new(10, 11));
    println!("ok");

    // 3.完全限定语法
    trait Poilt {
        fn fly(&self);
    }
    trait Wizard {
        fn fly(&self);
    }
    struct Human {
        name: String
    }
    impl Human {
        fn fly(&self) {
            println!("this is {}", self.name);
        }
    }
    impl Poilt for Human {
        fn fly(&self) {
            println!("this is poilt name: {}", self.name);
        }
    }
    impl Wizard for Human {
        fn fly(&self) {
            println!("this is Wizard name: {}", self.name);
        }
    }
    let human = Human {name: String::from("老林")};
    human.fly();
    Poilt::fly(&human);
    Wizard::fly(&human);
    // 但如果没有&self这个参数
    trait Animal {
        fn baby_name();
    }

    struct Dog;

    impl Dog {
        fn baby_name() {
            println!("this is dog")
        }
    }

    impl Animal for Dog {
        fn baby_name() {
            println!("this is Animal");
        }
    }
    Dog::baby_name();
    <Dog as Animal>::baby_name();
    // 4. supertrait
    trait OutlinePrint:fmt::Display {
        fn outline_print(&self) {
            let output = self.to_string();
            let len = output.len();
            println!("{}", "*".repeat(len + 4));
            println!("*{}*", " ".repeat(len + 2));
            println!("{}", output);
            println!("*{}*", " ".repeat(len + 2));
            println!("{}", "*".repeat(len + 4));
        }
    }
    struct Point {
        x: i32,
        y: i32
    }

    impl OutlinePrint for Point {}
    impl fmt::Display for Point {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "({}, {})", self.x, self.y)
        }
    }
    let point = Point {x: 11, y: 12};
    point.outline_print();
    // 5. newtype模式
    struct Wrapper(Vec<String>);
    impl fmt::Display for Wrapper {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "[{}]", self.0.join(","))
        }
    }
    let v = Wrapper(vec![
        String::from("hello"),
        String::from("world")
    ]);
    println!("wrapper: {}", v.to_string());
}